package com.tbit.uqbike.client.ordertrace;

import com.google.common.collect.Table;
import com.tbit.uqbike.client.common.Pair;

import java.util.Map;

/**
 * 状态转移组件实现
 *
 *
 * @author <a href="mailto:chen.chaoxiong@tbit.com.cn">ChenChaoXiong</a>
 * @since 2024/7/17
 */
public class StateTransitionComponentImpl implements StateTransitionComponent {

    // 状态转移表
    private final Table<OrderStage, Event, OrderStage> transitions;

    // 状态转移校验器
    private final Map<Pair<OrderStage, Event>, TransitionValidator> validators;

    public StateTransitionComponentImpl(Table<OrderStage, Event, OrderStage> transitions, Map<Pair<OrderStage, Event>, TransitionValidator> validators) {
        this.transitions = transitions;
        this.validators = validators;
    }

    /**
     * 获取下一个节点
     *
     * @param currentStage 当前节点
     * @param event 事件
     * @return 下一个节点
     * @throws InvalidTransitionException 无效的转移
     */
    @Override
    public OrderStage getNextStage(OrderStage currentStage, Event event) {
        if (!isValidTransition(currentStage, event)) {
            throw new InvalidTransitionException("Invalid transition from " + currentStage + " on event " + event);
        }
        return transitions.get(currentStage, event);
    }

    @Override
    public boolean accept(OrderStage currentStage, Event event) {
        return isValidTransition(currentStage, event);
    }

    /**
     * 是否是有效的转移
     * 状态转移表中包含当前节点和事件，并且校验器校验通过
     * @param currentStage 当前节点
     * @param event 事件
     * @return 是否是有效的转移
     */
    private boolean isValidTransition(OrderStage currentStage, Event event) {
        TransitionValidator validator = validators.get(new Pair<>(currentStage, event));
        return transitions.contains(currentStage, event) && (validator == null || validator.validateTransition(event.getData()));
    }
}
